x86 hvm: Simplify and consolidate logic for HLT emulation.
authorKeir Fraser <keir.fraser@citrix.com>
Tue, 6 May 2008 10:05:00 +0000 (11:05 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Tue, 6 May 2008 10:05:00 +0000 (11:05 +0100)
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen/arch/x86/hvm/hvm.c
xen/arch/x86/hvm/svm/svm.c
xen/arch/x86/hvm/vmx/vmx.c

index 6a7f20dc88d101ecfda20d44f52ae2120af5ae01..209b1a64b39ca970c8b311f4558f0c6df772991d 100644 (file)
@@ -46,6 +46,7 @@
 #include <asm/hvm/vpt.h>
 #include <asm/hvm/support.h>
 #include <asm/hvm/cacheattr.h>
+#include <asm/hvm/trace.h>
 #include <public/sched.h>
 #include <public/hvm/ioreq.h>
 #include <public/version.h>
@@ -739,15 +740,22 @@ void hvm_send_assist_req(struct vcpu *v)
 
 void hvm_hlt(unsigned long rflags)
 {
+    struct vcpu *curr = current;
+
+    if ( hvm_event_pending(curr) )
+        return;
+
     /*
      * If we halt with interrupts disabled, that's a pretty sure sign that we
      * want to shut down. In a real processor, NMIs are the only way to break
      * out of this.
      */
     if ( unlikely(!(rflags & X86_EFLAGS_IF)) )
-        return hvm_vcpu_down(current);
+        return hvm_vcpu_down(curr);
 
     do_sched_op_compat(SCHEDOP_block, 0);
+
+    HVMTRACE_1D(HLT, curr, /* pending = */ vcpu_runnable(curr));
 }
 
 void hvm_triple_fault(void)
index 4fd5c1bca0e6b246715d55325e51985a7fab6fe7..c52c1f5b2b54f30d921b97a1584162d2350c1fc9 100644 (file)
@@ -1099,25 +1099,13 @@ static void svm_do_msr_access(struct cpu_user_regs *regs)
 static void svm_vmexit_do_hlt(struct vmcb_struct *vmcb,
                               struct cpu_user_regs *regs)
 {
-    struct vcpu *curr = current;
-    struct hvm_intack intack = hvm_vcpu_has_pending_irq(curr);
     unsigned int inst_len;
 
-    inst_len = __get_instruction_length(curr, INSTR_HLT, NULL);
+    inst_len = __get_instruction_length(current, INSTR_HLT, NULL);
     if ( inst_len == 0 )
         return;
     __update_guest_eip(regs, inst_len);
 
-    /* Check for pending exception or new interrupt. */
-    if ( vmcb->eventinj.fields.v ||
-         ((intack.source != hvm_intsrc_none) &&
-          !hvm_interrupt_blocked(current, intack)) )
-    {
-        HVMTRACE_1D(HLT, curr, /*int pending=*/ 1);
-        return;
-    }
-
-    HVMTRACE_1D(HLT, curr, /*int pending=*/ 0);
     hvm_hlt(regs->eflags);
 }
 
index 387637b87cd45d50ce9a1f1159ad403c4519f576..4a348c06b8e832985886d5c8a1a7e2c0de491ab9 100644 (file)
@@ -1857,22 +1857,6 @@ gp_fault:
     return X86EMUL_EXCEPTION;
 }
 
-static void vmx_do_hlt(struct cpu_user_regs *regs)
-{
-    unsigned long intr_info = __vmread(VM_ENTRY_INTR_INFO);
-    struct vcpu *curr = current;
-
-    /* Check for pending exception. */
-    if ( intr_info & INTR_INFO_VALID_MASK )
-    {
-        HVMTRACE_1D(HLT, curr, /*int pending=*/ 1);
-        return;
-    }
-
-    HVMTRACE_1D(HLT, curr, /*int pending=*/ 0);
-    hvm_hlt(regs->eflags);
-}
-
 static void vmx_do_extint(struct cpu_user_regs *regs)
 {
     unsigned int vector;
@@ -2187,7 +2171,7 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs)
     case EXIT_REASON_HLT:
         inst_len = __get_instruction_length(); /* Safe: HLT */
         __update_guest_eip(inst_len);
-        vmx_do_hlt(regs);
+        hvm_hlt(regs->eflags);
         break;
     case EXIT_REASON_INVLPG:
     {